package com.plum.admin.modules.quartz.service.impl;

import com.plum.admin.common.exception.BaseException;
import com.plum.admin.modules.quartz.entity.SysQuartzJob;
import com.plum.admin.modules.quartz.mapper.SysQuartzJobMapper;
import com.plum.admin.modules.quartz.service.ISysQuartzJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 子丶沫
 * @since 2021-09-22
 */
@Service
public class SysQuartzJobServiceImpl extends ServiceImpl<SysQuartzJobMapper, SysQuartzJob> implements ISysQuartzJobService {
    @Autowired
    private Scheduler scheduler;
    @Override
    public void addJob(String jobClassName, String cronExpression, String parameter) {
        try {
            // 构建job信息
            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
                    .withIdentity(jobClassName)
                    .usingJobData("parameter", parameter)
                    .build();

            // 表达式调度构建器(即任务执行的时间) 使用withMisfireHandlingInstructionDoNothing() 忽略掉调度暂停过程中没有执行的调度
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();

            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName)
                    .withSchedule(scheduleBuilder).build();

            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error(e.toString());
            throw new BaseException("创建定时任务失败");
        } catch (Exception e) {
            throw new BaseException("后台找不到该类名任务");
        }
    }

    @Override
    public void deleteJob(String jobClassName) {
        try{
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
            scheduler.deleteJob(JobKey.jobKey(jobClassName));
        }catch (Exception e){
            throw new BaseException("删除定时任务失败");
        }
    }

    private Job getClass(String jobClassName){
        Class<?> forName = null;
        try {
            forName = Class.forName(jobClassName);
            Object newInstance = forName.getDeclaredConstructor().newInstance();
            return (Job)newInstance;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
}
